import random
import copy
import math

# TODO batch.evaluate
class ListBatch(list):
    def __init__(self, contents):
        list.__init__(self, contents)

    def evaluate(self, specimen):
        result = 0
        for e in self:
            result += self.compare(e[1], specimen.apply(e[0]))

        return result

def defaultCompare(target, output):
    """Computes the absolute Error."""
    result = 0
    for i in xrange(len(target)):
        result += math.fabs(target[i] - output[i])

    return result


class ListDomain(list):
    def __new__(cls, contents, *args):
        return list.__new__(cls, contents)

    def __init__(self, contents, batch_size, compare_result = None, batchType = ListBatch):
        list.__init__(self, contents)
        self.batch_size = batch_size

        if compare_result is None:
            compare_result = defaultCompare

        class MyBatchType(batchType):
            def __init__(self, contents):
                batchType.__init__(self, contents)

            def compare(self, target, output):
                return compare_result(target, output)


        self.new_batch = MyBatchType

        self.input_size = len(self[0][0])
        self.output_size = len(self[0][1])


    def getBatch(self):
        result = []

        for i in xrange(self.batch_size):
            result.append(random.choice(self))

        return self.new_batch(result)

    def quicktest(self, specimen):
        return self.getBatch().evaluate(specimen)
